/*
* @Date: 2021/2/23
* @Author: XueChengwu <xuechengwu@erayt.com>
* @Copyright: 2015-2019 Erayt, Inc.
* @Description: If you have some questions, please contact: xuechengwu@erayt.com.
*/
import controller from '../core/controller'
import { get, post } from '../core/route';
import { db, tran, id } from '../core/db/mysql/db';
import Query from '../core/db/mysql/query';
import { check_captcha, no_repeat } from '../behaviour/common';
import { login } from '../decorater/auth';
import Validator from '../core/validator'
import UserValidator from '../validator/buUser';
import i18n from '../core/i18n';
import utils from '../core/utils';
import md5 from 'md5';
import config from '../core/config';
import fs from 'fs';
import path from 'path';

@controller()
export default class user{
  @post('/api/register')
  async register() {
    const user = this.params;
    console.log('user===>', user);
    // if(!await this.__todo(check_captcha, this.params.captcha)) {
    //   return this.setCode(1).setMsg(i18n.captcha).json()
    // }
    let validator = new Validator(UserValidator);
    let res = await validator.scene('register').check(user);
    if(res !== true) {
      return this.setCode(1).setMsg(res).json();
    }
    const tranResult = await tran(async conn => {
      if(!await this.__todo(no_repeat, conn, this.params, 'username', 'bu_user')){
        return this.setMsg(i18n.repeat.username), false
      }
      try {
        const file = this.ctx.request.files.avatar;
        const reader = fs.createReadStream(file.path);
        const dir = config.upload.path + '/' + utils.formatDate(new Date(), 'yyyyMMdd');
        const filePath = dir + `/${utils.getGuid()}.${file.name.substr(file.name.lastIndexOf('.') + 1)}`;
        const isExists = fs.existsSync(path.join(__dirname, `../static/${dir}`));
        if(!isExists) {
          fs.mkdirSync(path.join(__dirname, `../static/${dir}`));
        }
        const absolutePath = path.join(__dirname, `../static/${filePath}`);
        const upStream = fs.createWriteStream(absolutePath);
        reader.pipe(upStream);
        const userQuery = new Query(conn, 'bu_user');
        const accountQuery = new Query(conn, 'bu_account');
        const userModal = {
          addtime: utils.formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss'),
          password: md5(user.password),
          username: user.username,
          tel: user.tel || '',
          email: user.email,
          avatar: filePath,
        };
        await userQuery.insert(userModal);
        const userId = await id(conn);
        const account = {
          user: userId,
          type: 0,
          amount: 100000,
          status: 1,
          addtime: utils.formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss'),
        };
        await accountQuery.insert(account);
        return true;
      } catch(err) {
        throw err;
        return false;
      }
    });
    if (tranResult) {
      return this.setCode(0).json();
    }
    return this.setCode(1).json();
  }

  @post('/api/login')
  async login() {
    // if(!await this.__todo(check_captcha, this.params.captcha)) {
    //   return this.setCode(1).setMsg(i18n.captcha).json()
    // }
    let validator = new Validator(UserValidator);
    console.log('login===>', this.params);
    let res = await validator.scene('login').check(this.params)
    if(res !== true) {
      return this.setCode(1).setMsg(res).json()
    }
    const passResult = await db(async conn => {
      try{
        let query = new Query(conn, 'bu_user')
        const username = this.params.username;
        let res = await query.where('username', username).where('or', 'tel', username).find();
        if(res && res.password === md5(this.params.password)){
          this.session.userid = res.id;
          this.session.username = res.username;
          delete res.password;
          this.assign('user', res);
          return true
        }else {
          return false
        }
      }catch(err) {
        return false
      }
    });
    if (passResult) {
      return this.setCode(0).setMsg(i18n.user.login.success).json();
    }
    return this.setCode(1).setMsg(i18n.user.login.error).json();
  }

  @login
  @post('/api/logout')
  async logout() {

  }

  @login
  @get('/api/user/accounts')
  async accounts() {
    const userid = this.session.userid;
    await db(async conn => {
      const accountQuery = new Query(conn, 'bu_account');
      const accounts = accountQuery.where('user', userid).where('status', 1).select();
      this.assign('accounts', accounts);
    });
    return this.setCode(0).setMsg(i18n.success).json();
  }

  @login
  @post('/api/user/star')
  async star() {
    const { starUser, status = 0 } = this.params;
    const { userid } = this.session;
    try {
      await tran(async conn => {
        const userStarQuery = new Query(conn, 'bu_user_star');
        const userQuery = new Query(conn, 'bu_user');
        if (Number(status) === 0) {
          // 关注
          const userStar = await userStarQuery.where('user', userid)
            .where('starUser', starUser)
            .find();
          if (!userStar) {
            await userStarQuery.insert({
              user: userid,
              starUser: starUser,
              addtime: utils.formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss'),
            });
            const user = await userQuery.where('id', starUser).find();
            await userQuery.where('id', user.id).update({
              stars: Number(user.stars) + 1,
            });
          }
        } else {
          // 取消关注
          await userStarQuery.where('user', userid)
            .where('starUser', starUser)
            .delete();
          const user = await userQuery.where('id', starUser).find();
          await userQuery.where('id', user.id).update({
            stars: Number(user.stars) - 1,
          });
        }
      });
      return this.setCode(0).setMsg(Number(status) === 0 ? '关注成功' : '取消成功').json();
    } catch (err) {
      console.log('error===>', err);
      return this.setCode(1).setMsg('操作失败').json();
    }
  }

  @login
  @get('/api/user/stars')
  async getStars() {
    const { userid } = this.session;
    try {
      await db(async conn => {
        const userStarQuery = new Query(conn, 'bu_user_star');
        const stars = await userStarQuery
          .alias('us')
          .join('bu_user u', 'us.starUser = u.id', 'LEFT')
          .fields('u.username, u.avatar, u.id as userid')
          .where('us.user', userid).select();
        this.assign('stars', stars);
      });
      return this.setCode(0).setMsg('获取成功').json();
    } catch(err) {
      console.log('error====>', err);
      return this.setCode(1).setMsg('获取失败').json();
    }
  }
}
